package com.gylang.print.pdf.test.docx;

import lombok.extern.slf4j.Slf4j;
import org.docx4j.jaxb.Context;
import org.docx4j.openpackaging.exceptions.Docx4JException;
import org.docx4j.openpackaging.exceptions.InvalidFormatException;
import org.docx4j.openpackaging.packages.WordprocessingMLPackage;
import org.docx4j.openpackaging.parts.WordprocessingML.MainDocumentPart;
import org.docx4j.wml.*;

import java.io.File;
import java.math.BigInteger;
import java.util.List;

/**
 * @author gylang
 * data 2021/6/2
 */
@Slf4j
public class SampleDoc {
	public static final String BASE = "E:/test/RuoYi-Vue-gylang-integration/doc/docx/";

	public static void main(String[] args) throws Docx4JException {
		// 创建文件
//		createDocx();
		// 简单写入数据
		writeText();
		// 工厂 追加数据
		paragraph();
		// 读取数据
		read();
		// 表格
		addTable();
	}

	private static void writeText() throws Docx4JException {
		WordprocessingMLPackage wordMLPackage = WordprocessingMLPackage.createPackage();
		//这是文件描述的标题
		wordMLPackage.setTitle("这是个测试标题1");
		wordMLPackage.setTitle("这是个测试标题2");
		wordMLPackage.setTitle("这是个测试标题3");

		// 写入数据
		MainDocumentPart mainDocumentPart = wordMLPackage.getMainDocumentPart();
		mainDocumentPart.addParagraphOfText("这是啥: addParagraphOfText");
		mainDocumentPart.addStyledParagraphOfText("Title", "我是个标题?");
		mainDocumentPart.addStyledParagraphOfText("Subtitle", "我是个子标题?");
		mainDocumentPart.addStyledParagraphOfText("Subtitle", "我是个子标题?");
		mainDocumentPart.addParagraphOfText("这是啥: addParagraphOfText? 我是正文?");

		wordMLPackage.save(new File(BASE + "title3times.docx"));
	}

	/**
	 * 段落
	 *
	 * @throws Docx4JException
	 */
	private static void paragraph() throws Docx4JException {
		try {
			WordprocessingMLPackage wordprocessingMLPackage = WordprocessingMLPackage
				.load(new File(BASE + "title3times.docx"));
			ObjectFactory factory = Context.getWmlObjectFactory();
			P para = factory.createP();
			if ("我要加个段落试试" != null) {
				Text t = factory.createText();
				t.setValue("我要加个段落试试");
				R run = factory.createR();
				run.getContent().add(t);
				para.getContent().add(run);
			}
			wordprocessingMLPackage.getMainDocumentPart().getContent().add(para);
			wordprocessingMLPackage.save(new File(BASE + "title3times.docx"));
		} catch (Exception e) {
			log.error("addParagraph to docx error: Docx4JException", e);
		}
	}

	/**
	 * 段落
	 *
	 * @throws Docx4JException
	 */
	private static void read() throws Docx4JException {
		try {
			WordprocessingMLPackage wordprocessingMLPackage = WordprocessingMLPackage
				.load(new File(BASE + "table.docx"));

			String contentType = wordprocessingMLPackage.getContentType();
			log.info("contentType -> {}", contentType);

			MainDocumentPart mainDocumentPart = wordprocessingMLPackage.getMainDocumentPart();
			List<Object> content = mainDocumentPart.getContent();
			for (Object ob : content) {
				log.info("ob -> {}", ob);
			}
		} catch (Docx4JException e) {
			log.error("createDocx error: Docx4JException", e);
		}
	}

	/**
	 * 创建一个简单的docx
	 */
	private static void createDocx() {
		// Create the package
		WordprocessingMLPackage wordMLPackage;
		try {
			wordMLPackage = WordprocessingMLPackage.createPackage();
			// 另存为新的文件
			wordMLPackage.save(new File(BASE + "SampleDoc.docx"));
		} catch (InvalidFormatException e) {
			log.error("createDocx error:InvalidFormatException", e);
		} catch (Docx4JException e) {
			log.error("createDocx error: Docx4JException", e);
		}
	}

	/**
	 * 创建一个表格
	 */
	public static void addTable() {
		try {
			WordprocessingMLPackage wordMLPackage = WordprocessingMLPackage.createPackage();
			ObjectFactory factory = Context.getWmlObjectFactory();
			MainDocumentPart mainDocumentPart = wordMLPackage.getMainDocumentPart();

			// 0. 创建表格元素
			Tbl table = factory.createTbl();

			// 1.显示表格的边框
			addBorders(table);

			// 2.添加表格内容(创建行和列)
			for (int i = 0; i < 3; i++) {
				Tr tr = factory.createTr();
				for (int j = 0; j < 3; j++) {
					Tc tc = factory.createTc();

					// P p = mainDocumentPart.createParagraphOfText("---row" + i
					// + "---column" + j + "---");
					// 第二种创建P并设置样式的方法
					P p1 = factory.createP();
					R r = factory.createR();
					Text text = factory.createText();
					text.setValue("---row" + i + "---column" + j + "---");

					r.getContent().add(text);
					p1.getContent().add(r);

					// 2.1通过R设置字体加粗等属性
					setRStyle(r);
					// 2.2设置列宽
					if (j == 1) {
						setCellWidth(tc, 1250);
					} else {
						setCellWidth(tc, 2500);
					}

					tc.getContent().add(p1);
					tr.getContent().add(tc);

				}
				table.getContent().add(tr);
			}

			// 3.合并单元格

			// 3.加表格加到主要内容中
			mainDocumentPart.addObject(table);
			wordMLPackage.save(new java.io.File(BASE + "table.docx"));
		} catch (Docx4JException e) {
			log.error("createDocx error: Docx4JException", e);
		}
	}

	/**
	 * 设置列宽
	 *
	 * @param tc
	 * @param width
	 */
	private static void setCellWidth(Tc tc, int width) {
		TcPr tableCellProperties = new TcPr();
		TblWidth tableWidth = new TblWidth();
		tableWidth.setW(BigInteger.valueOf(width));
		tableCellProperties.setTcW(tableWidth);

		tc.setTcPr(tableCellProperties);
	}

	/**
	 * 通过设置R设置表格中属性字体加粗，大小为25
	 *
	 * @param
	 */
	private static void setRStyle(R r) {
		// 1.创建一个RPr
		RPr rpr = new RPr();

		// 2.设置RPr
		// 2.1设置字体大小
		HpsMeasure size = new HpsMeasure();
		size.setVal(new BigInteger("25"));
		rpr.setSz(size);
		// 2.2设置加粗
		BooleanDefaultTrue bold = new BooleanDefaultTrue();
		bold.setVal(true);
		rpr.setB(bold);

		// 3.将RPr设置为R的属性
		r.setRPr(rpr);
	}

	/**
	 * 设置边框样式
	 *
	 * @param table 需要设置表格边框的单元格
	 */
	private static void addBorders(Tbl table) {
		table.setTblPr(new TblPr());// 必须设置一个TblPr，否则最后会报空指针异常

		CTBorder border = new CTBorder();
		border.setColor("auto");
		border.setSz(new BigInteger("4"));
		border.setSpace(new BigInteger("0"));
		border.setVal(STBorder.SINGLE);

		TblBorders borders = new TblBorders();
		borders.setBottom(border);
		borders.setLeft(border);
		borders.setRight(border);
		borders.setTop(border);
		borders.setInsideH(border);
		borders.setInsideV(border);

		// 获取其内部的TblPr属性设置属性
		table.getTblPr().setTblBorders(borders);
	}
}
